<?php

namespace support\coze;

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\MultipartStream;

class Factory
{
    private static $instance;

    private $token;

    const BASE_URL = 'https://api.coze.cn';

    private function __construct($token)
    {
        $this->token = $token;
    }

    public static function getInstance(...$args)
    {
        if (is_null(self::$instance)) {
            self::$instance = new self(...$args);
        }

        return self::$instance;
    }

    public function getClient()
    {
        return new Client(['base_uri' => self::BASE_URL, 'headers' => [
            'Authorization' => 'Bearer ' . $this->token,
            'Content-Type' => 'application/json',
        ]]);
    }

    public function uploadFile($file)
    {
        $multipart = [
            [
                'name' => 'file',
                'contents' => fopen($file, 'r'),
                'filename' => basename($file)
            ],
        ];

        $body = new MultipartStream($multipart);

        $res = $this->getClient()->post('/v1/files/upload', [
            'body' => $body,
            'headers' => [
                'Content-Type' => 'multipart/form-data; boundary=' . $body->getBoundary()
            ],
        ]);

        $data = json_decode($res->getBody()->getContents(), true);


        if ($data['code'] == 0) {
            return $data['data'];
        } else {
            throw new \Exception($data['msg']);
        }
    }

    public function asyncRunWorkFlow($workFlowId, $params)
    {
        $body = json_encode([
            'workflow_id' => $workFlowId,
            'parameters' => $params,
            'is_async' => true,
        ]);

        $res = $this->getClient()->post('/v1/workflow/run', [
            'body' => $body,
        ]);

        $data = json_decode($res->getBody()->getContents(), true);

        if ($data['code'] == 0) {
            return $data;
        } else {
            throw new \Exception($data['msg']);
        }
    }

    public function runWorkFlow($workFlowId, $params)
    {
        $body = json_encode([
            'workflow_id' => $workFlowId,
            'parameters' => $params,
        ]);

        $res = $this->getClient()->post('/v1/workflow/run', [
            'body' => $body,
        ]);

        $data = json_decode($res->getBody()->getContents(), true);

        if ($data['code'] == 0) {
            return $data;
        } else {
            throw new \Exception($data['msg']);
        }
    }

    public function queryRunWorkFlow($workFlowId, $excuteId)
    {
        $res = $this->getClient()->get("/v1/workflows/{$workFlowId}/run_histories/{$excuteId}");

        $body = json_decode($res->getBody()->getContents(), true);

        if ($body['code'] == 0) {
            return $body;
        } else {
            throw new \Exception($body['msg']);
        }
    }
}